// 库存业务处理

package template

import (
	dbModel "ZHONGYIHANGYAN/bean/dbModel"
	"ZHONGYIHANGYAN/bean/request"
	"ZHONGYIHANGYAN/bean/response"
	"fmt"
	"strings"
	"time"

	commUtils "ZHONGYIHANGYAN/commUtils"

	"gorm.io/gorm"
)

// 获取模板列表
func (manage *TemplateManage) GetTemplateList(query *request.GetTemplateListQuery) (response.PageData, error) {
	pageData := response.PageData{}

	db := manage.DataBase.DB()
	tx := db.Model(&dbModel.Template{}).Joins("LEFT JOIN user ON template.create_user_code = user.user_code")
	selectClause := `
        template.*, 
        user.user_name AS create_user_name
    `
	tx = tx.Select(selectClause)

	if query.Name != "" {
		tx = tx.Where("template.name like ?", "%"+query.Name+"%")
	}

	// 获取总记录数
	var total int64
	if err := tx.Count(&total).Error; err != nil {
		return pageData, err
	}
	if total == 0 {
		pageData.List = []interface{}{}
		return pageData, nil
	}

	// 分页查询
	currentPage := query.CurrentPage
	numPerPage := query.NumPerPage
	if currentPage <= 0 {
		currentPage = 1
	}
	if numPerPage <= 0 {
		numPerPage = 50
	}
	offset := (currentPage - 1) * numPerPage
	tx = tx.Order("create_time DESC").Limit(numPerPage).Offset(offset)

	var templateList []response.GetTemplateListResponseInfo
	if err := tx.Find(&templateList).Error; err != nil {
		return pageData, err
	}

	pageData.CurrentPage = currentPage
	pageData.NumPerPage = numPerPage
	pageData.TotalCount = int(total)
	pageData.TotalPages = (pageData.TotalCount + numPerPage - 1) / numPerPage
	pageData.List = templateList

	return pageData, nil
}

// 添加模板、修改模板
func (manage *TemplateManage) AddOrUpdateTemplate(info *request.AddOrUpdateTemplateQuery) error {
	return manage.DataBase.DB().Transaction(func(tx *gorm.DB) error {
		// 判断是创建还是更新。优先检查指针是否为nil，避免panic。
		isUpdate := info.Id != ""

		if !isUpdate {
			// --- 分支：创建新模板 ---
			return createTemplateWithQuotas(tx, info)
		} else {
			// --- 分支：更新现有模板 ---
			return updateTemplateWithQuotas(tx, info)
		}
	})
}

// createTemplateWithQuotas 负责处理创建新模板及其关联指标的逻辑
func createTemplateWithQuotas(tx *gorm.DB, info *request.AddOrUpdateTemplateQuery) error {
	template := dbModel.Template{
		Id:   commUtils.GenUUID(),
		Name: info.Name,
		Note: info.Note,
	}
	template.CreateUserCode = info.CreateUserCode

	// 1. 创建模板
	if err := tx.Create(&template).Error; err != nil {
		return fmt.Errorf("创建模板失败: %w", err)
	}

	// 2. 如果有指标，批量创建指标
	if len(info.QuotaList) > 0 {
		for i := range info.QuotaList {
			info.QuotaList[i].TemplateId = template.Id
			info.QuotaList[i].Id = commUtils.GenUUID()
		}

		if err := tx.Create(&info.QuotaList).Error; err != nil {
			return fmt.Errorf("批量创建指标失败: %w", err)
		}
	}

	return nil
}

// updateTemplateWithQuotas 负责处理更新模板及其关联指标（全量替换）的逻辑
func updateTemplateWithQuotas(tx *gorm.DB, info *request.AddOrUpdateTemplateQuery) error {
	templateID := info.Id

	// 1. 验证并更新模板主体信息
	templateUpdates := map[string]interface{}{
		"Name": info.Name,
		"Note": info.Note,
	}
	// 使用 map 进行更新更安全、更清晰
	result := tx.Model(&dbModel.Template{}).Where("id = ?", templateID).Updates(templateUpdates)
	if result.Error != nil {
		return fmt.Errorf("更新模板失败: %w", result.Error)
	}
	if result.RowsAffected == 0 {
		return fmt.Errorf("更新失败：未找到ID为 %s 的模板", templateID)
	}

	// --- 全量处理指标 ---

	// 2. 获取数据库中该模板现有的所有指标ID
	var existingQuotaIDs []string
	if err := tx.Model(&dbModel.Quota{}).Where("template_id = ?", templateID).Pluck("id", &existingQuotaIDs).Error; err != nil {
		return fmt.Errorf("获取现有指标ID失败: %w", err)
	}

	quotasToUpdate := make([]request.Quota, 0)
	quotasToCreate := make([]request.Quota, 0)
	incomingQuotaIDs := make(map[string]bool)

	// 3. 遍历传入的指标列表，将它们分类为“待更新”和“待创建”
	for _, quota := range info.QuotaList {
		quota.TemplateId = templateID // 确保关联正确
		if quota.Id != "" {
			// 有ID的，加入待更新列表
			quotasToUpdate = append(quotasToUpdate, quota)
			incomingQuotaIDs[quota.Id] = true
		} else {
			// 没有ID的，加入待创建列表
			quota.Id = commUtils.GenUUID()
			quota.TemplateId = templateID
			quotasToCreate = append(quotasToCreate, quota)
		}
	}

	// 4. 计算需要删除的指标ID（存在于数据库，但不存在于传入列表）
	var quotasToDelete []string
	for _, existingID := range existingQuotaIDs {
		if _, ok := incomingQuotaIDs[existingID]; !ok {
			quotasToDelete = append(quotasToDelete, existingID)
		}
	}

	// 5. 执行数据库操作
	// 5a. 删除不再需要的指标
	if len(quotasToDelete) > 0 {
		if err := tx.Where("id IN ?", quotasToDelete).Delete(&dbModel.Quota{}).Error; err != nil {
			return fmt.Errorf("删除旧指标失败: %w", err)
		}
	}
	// 5b. 更新已存在的指标
	for _, quota := range quotasToUpdate {
		// 使用 Save 来更新，它会根据主键更新所有字段
		if err := tx.Save(&quota).Error; err != nil {
			return fmt.Errorf("更新指标 (Id: %s) 失败: %w", quota.Id, err)
		}
	}
	// 5c. 批量创建新指标
	if len(quotasToCreate) > 0 {
		if err := tx.Create(&quotasToCreate).Error; err != nil {
			return fmt.Errorf("创建新指标失败: %w", err)
		}
	}

	return nil
}

// 删除模板
func (manage *TemplateManage) DeleteTemplate(templateIds []string) error {
	if len(templateIds) == 0 {
		return nil
	}

	db := manage.DataBase.DB()
	result := db.Where("id IN ?", templateIds).Delete(&dbModel.Template{})
	if result.Error != nil {
		return result.Error
	}
	if result.RowsAffected == 0 {
		return fmt.Errorf("没有找到要删除的记录，ID列表可能无效或记录已被删除")
	}
	return nil
}

// 复制模板
func (manage *TemplateManage) CopyTemplate(templateIds []string) error {
	// 遍历需要复制的每一个模板ID
	for _, id := range templateIds {
		err := manage.DataBase.DB().Transaction(func(tx *gorm.DB) error {
			// 1、查找原始模板和其所有关联的指标
			var originalTemplate dbModel.Template
			if err := tx.Where("id = ?", id).First(&originalTemplate).Error; err != nil {
				return fmt.Errorf("查找原始模板失败 (Id: %s): %w", id, err)
			}

			var originalQuotas []dbModel.Quota
			if err := tx.Where("template_id = ?", id).Order("id ASC").Find(&originalQuotas).Error; err != nil {
				return fmt.Errorf("查找模板关联的指标失败 (TemplateID: %s): %w", id, err)
			}

			// 2、创建新的模板副本
			copySuffix := fmt.Sprintf("-Copy-%d", time.Now().Unix())
			newTemplate := dbModel.Template{
				Id:             commUtils.GenUUID(),
				Name:           originalTemplate.Name + copySuffix,
				CreateUserCode: originalTemplate.CreateUserCode,
				Note:           originalTemplate.Note,
			}
			if err := tx.Create(&newTemplate).Error; err != nil {
				return fmt.Errorf("创建新模板失败: %w", err)
			}
			// 如果原始模板没有关联指标，则复制完成
			if len(originalQuotas) == 0 {
				return nil
			}

			// 3、批量准备并创建新的指标副本
			newQuotas := make([]dbModel.Quota, 0, len(originalQuotas))
			for _, quota := range originalQuotas {
				newQuota := dbModel.Quota{
					Id:                 commUtils.GenUUID(),
					Name:               quota.Name,
					Level:              quota.Level,
					EvaluationCriteria: quota.EvaluationCriteria,
					EvaluationScore:    quota.EvaluationScore,
					Note:               quota.Note,
					TemplateId:         newTemplate.Id,
					// 暂时不设置 ParentQuotaId，因为新的父指标ID还不存在
					ParentQuotaId: "",
				}
				newQuotas = append(newQuotas, newQuota)
			}
			if err := tx.Create(&newQuotas).Error; err != nil {
				return fmt.Errorf("批量创建指标失败: %w", err)
			}

			// 填充 old-Id -> new-Id 的映射
			oldToNewQuotaIDMap := make(map[string]string)
			for i, oq := range originalQuotas {
				oldToNewQuotaIDMap[oq.Id] = newQuotas[i].Id
			}

			var updateClauses []string
			var idsToUpdateParent []string
			for _, oq := range originalQuotas {
				if oq.ParentQuotaId != "" {
					if newParentID, ok := oldToNewQuotaIDMap[oq.ParentQuotaId]; ok {
						childID := oldToNewQuotaIDMap[oq.Id]
						updateClauses = append(updateClauses, fmt.Sprintf("WHEN '%s' THEN '%s'", childID, newParentID))
						idsToUpdateParent = append(idsToUpdateParent, childID)
					}
				}
			}

			if len(updateClauses) > 0 {
				caseSQL := "CASE id " + strings.Join(updateClauses, " ") + " END"
				if err := tx.Model(&dbModel.Quota{}).Where("id IN ?", idsToUpdateParent).Update("parent_quota_id", gorm.Expr(caseSQL)).Error; err != nil {
					return fmt.Errorf("批量更新指标父子关系失败: %w", err)
				}
			}

			return nil
		})

		// 如果事务执行过程中返回了任何错误，则立即停止并向上返回该错误
		if err != nil {
			return err
		}
	}

	return nil
}

// 查看模板详情
func (manage *TemplateManage) GetTemplateDetail(templateId string) (*response.GetTemplateDetailResponse, error) {
	// 定义临时结构体接收 JOIN 查询结果
	type TemplateWithUser struct {
		dbModel.Template
		CreateUserName string `gorm:"column:create_user_name"`
	}

	var templateWithUser TemplateWithUser
	// 使用 JOIN 查询模板和用户表，一次查询获取所有需要的字段，提高性能
	err := manage.DataBase.DB().
		Model(&dbModel.Template{}).
		Select("template.*, user.user_name AS create_user_name").
		Joins("LEFT JOIN user ON template.create_user_code = user.user_code").
		Where("template.id = ?", templateId).
		First(&templateWithUser).Error

	if err != nil {
		return nil, fmt.Errorf("查找模板失败 (Id: %s): %w", templateId, err)
	}

	// 查询模板关联的指标信息
	var quotas []dbModel.Quota
	if err := manage.DataBase.DB().Where("template_id = ?", templateId).Order("id ASC").Find(&quotas).Error; err != nil {
		return nil, fmt.Errorf("查找模板关联的指标失败 (TemplateID: %s): %w", templateId, err)
	}

	// 转换指标数据格式
	quotaList := make([]response.QuotaListResponseInfo, len(quotas))
	for i, quota := range quotas {
		// 处理 EvaluationScore 从 *int 到 int 的转换
		evaluationScore := 0
		if quota.EvaluationScore != nil {
			evaluationScore = *quota.EvaluationScore
		}

		// 处理 EvaluationCriteria 中的换行符，确保前端能正确显示
		evaluationCriteria := quota.EvaluationCriteria
		// 如果数据库中的换行符被转义了，需要还原
		if strings.Contains(evaluationCriteria, "\\n") {
			evaluationCriteria = strings.ReplaceAll(evaluationCriteria, "\\n", "\n")
		}

		quotaList[i] = response.QuotaListResponseInfo{
			Id:                 quota.Id,
			Name:               quota.Name,
			Level:              quota.Level,
			EvaluationCriteria: evaluationCriteria,
			EvaluationScore:    evaluationScore,
			Note:               quota.Note,
			TemplateId:         quota.TemplateId,
		}
	}

	return &response.GetTemplateDetailResponse{
		Id:             templateId,
		Name:           templateWithUser.Name,
		CreateUserCode: templateWithUser.CreateUserCode,
		CreateUserName: templateWithUser.CreateUserName,
		Note:           templateWithUser.Note,
		CreateTime:     templateWithUser.CreateTime.Format("2006-01-02 15:04:05"),
		QuotaList:      quotaList,
	}, nil
}
